perm filename TEX82.BUG[TEX,DEK]2 blob sn#690331 filedate 1982-12-08 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00008 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	Updates to the TeX82 listing published in September, 1982.
C00005 00003	Changes to TEX.WEB made after Version 0 was released in October, 1982.
C00017 00004	A major change (Version 0.6) made on October 28:
C00029 00005	The ill-fated Version 0.7
C00032 00006	Changes subsequent to Version 0.6
C00044 00007	A major change (Version 0.8) made on November 14--16:
C00050 00008	Changes after version 0.8
C00056 ENDMK
C⊗;
Updates to the TeX82 listing published in September, 1982.
(These changes were included in the original Version 0 of TeX, but they
were discovered after the listing went to press.)

1. Module 943, line 6 (bug discovered 9/28)
change "if cur_cmd=char_num then" to
	if (cur_cmd=letter) ∨ (cur_cmd=other_char) then r←qi(cur_chr)
	else if cur_cmd=char_num then

2. "pause" changed to "pausing" and "pause_code" to "pausing code", throughout.

3. Module 719, lines 8 and 11 (bug discovered 9/28)
insert "rule_save←overfull_rule; overfull_rule←0;" after "save_ptr-2;"
insert "overfull_rule←rule_save;" before "q←p+list_offset;"
and insert a declaration of "overfull_rule: scaled" in module 716.

4. Module 1128, lines 6 and following (bug discovered 9/28)
change "while n≠0 do" to "loop"
change "goto done" to
	begin scan_left_brace; new_save_level(false_group);
	goto done;
	end
change "... return 1130>;" to
		... return 1130>
	else if n=0 then
		begin new_save_level(case_group); goto done;
		end;
and change "done: ... (false_group);" to "done:".

5. Module 182, line 10 (suggestion by DRF on 9/30)
change "0.0" to "?.?"

6. Module 682, new definition of math_spacing (decision of 10/2)
"0234000122*4000133**3**344*0400400*000000234000111*4111112341011"

7. Module 684, new code for case "4" (decision of 10/2)
"4": if cur_style<script_style then x:=thick_mu_skip_code else x:=0;
[Also in module 682 line 7, say "...a conditional thick space (\nonscript..."]

8. Module 11, trie_size changed from 7000 to 8000 because of new
improved (but longer) hyphenation patterns (10/4)

9. Module 453, forgot to change this when 454 changed (noted by DRF 10/6)
format_default_length=20 (not 22)
format_area_length=11 (not 13)

Changes to TEX.WEB made after Version 0 was released in October, 1982.

Since copies of TEX.WEB are not supposed to be edited, there are
two ways to make your version of TeX bug-free:
	1. Get a new copy of TEX.WEB.
	2. Put the corrections into your change file(s).
Some people will find (1) easier than (2), except the main TeX sources at
SCORE won't be updated quite as fast as the sources at SAIL (which have to
be translated into ascii before they are sent to the outside world).
Actually (2) will be quite easy, unless the list of changes becomes quite
long, so it is the recommended procedure. In case (2) it would be useful
to include a comment like "this is fix number xx" (using the numbering
scheme in this file), so that the change could readily be deleted at some
future time.

10. Module 857 line -5 (bug discovered 10/8/92 by HWT)
change it to: if h>0 then decr(h) else h←trie_op_hash_size;

11. Module 457 line 3 (typo discovered 10/9/82)
change `\.!' to `\.\&'

12. Module 1245 line 8 (bug fixed 10/9/82, discovered by MMD)
insert the following between "begin" and "if":
if format_ident≠0 then initialize; {erase preloaded format}

** Version 0.1 incorporates the above changes.

13. This is an extension to the language, put in to satisfy people who
objected to the fact that \write (and \openout and \closeout) only
caused action after being deferred to the next \shipout. Some applications
call for immediate output, hence a new feature: \immediate followed by
\openout or \write or \closeout causes the output action to take place
without delay. For example, \immediate\write{x} is equivalent to
\shipout\vbox{\write{x}} except that the latter also puts an empty
page into the DVI file.

The extension requires the following new code:
13a. Insert `\immediate' after `\closeout' in module 1248.
13b. Define immediate_code=4 and include the following in module 1252:
	primitive("immediate",extension,immediate_code);
13c. Include the following in module 1254:
	immediate_code:print_esc("immediate");
13d. And, in module 1256:
	immediate_code:@<Implement \.{\\immediate}@>;
13e. Finally, there's a new module inserted after old module 1280.
Here is the WEB coding for this module:

@ The presence of `\.{\\immediate}' causes the |do_extension| procedure
to descend to one level of recursion. Nothing happens unless \.{\\immediate}
is followed by `\.{\\openout}', `\.{\\write}', or `\.{\\closeout}'.
@↑recursion@>

@<Implement \.{\\immediate}@>=
begin get_nc_token;
if (cur_cmd=extension)∧(cur_chr≤close_node) then
	begin p←tail; do_extension; {append a whatsit node}
	out_what(tail); {do the action immediately}
	flush_node_list(tail); tail←p; link(p)←null;
	end
else back_input;
end;

** Version 0.2 incorporates the above changes.

14. Like change 11, this one doesn't affect the program, it just improves
the documentation: Insert the following definitions in module 106:
define set_glue_ratio_zero(#) == #:=0.0 {assign representation of zero ratio}
define set_glue_ratio_one(#) == #:=1.0 {assign representation of unit ratio}

These macros are now introduced in a dozen or so future modules, thereby
eliminating most of the system-dependent changes needed elsewhere for ratios.
(Note: I also changed 0 to 0.0 in two places of module 182, where a glue_ratio
comparision was being made.)

15. Change of module 576 (discovered by HWT, 10/14/82)
"hd:quarterword" should be "hd:eight_bits".
(The same error occurs in module 522, but in that module the remedy is
simply to delete the declaration of hd, since this variable is no longer used.)

16. A most embarrassing bug (discovered by DRF, 10/14/82)
Replace module 531 by:

@ A mild optimization of the output is performed by the |dvi_pop|
routine, which issues a |pop| unless it is possible to cancel a
`|push| |pop|' pair. The parameter to |dvi_pop| is the byte address
following the old |push| that matches the new |pop|.

@p procedure dvi_pop(@!l:integer);
begin if (l=dvi_offset+dvi_ptr)and(dvi_ptr>0) then decr(dvi_ptr)
else dvi_out(pop);
end;

Now we need to make a few changes to subsequent modules:
16a. In 549, after "incr(cur_s)", insert
	if cur_s>0 then dvi_out(push);
and before "decr(cur_s)", insert
	if cur_s>0 then dvi_pop(save_loc);

16b. Delete "dvi_out(push);" and "dvi_pop;" from modules 553, 558, 562, 567.

16c. Change module 559 just as in 16a.

17. Module 605, line 6 (discovered 10/15/82)
The test should be "prev_depth>ignore_depth"

** Version 0.3 incorporates the above changes.

18. Module 11 (noticed by WLS, 10/16/82)
Delete the definition of align_size (it's harmless but never used)

19. (This change and the next cause major changes to the TRIP output;
file TRIP.LOG and its relatives are being kept up to date on area [tug,dek].)
The change avoids error messages when vpackage is called during output.
Such messages can occur when there was no error, because the page is being
boxed without the \skip glue from its insertions; so they should be omitted.
The user who really wants such messages can still get them by saying
"\setbox255=\vbox to 1ht255{\unbox255}".
In module 903, insert the followng before the declaration of "wait":
	save_vbadness:integer; {saved value of |vbadness|}
	save_vfuzz: scaled; {saved value of |vfuzz|}
Then in module 924, insert
	save_vbadness:=vbadness; vbadness:=inf_bad;
	save_vfuzz:=vfuzz; vfuzz:=max_dimen; {inhibit error messages}
before the call on vpackage, and
	vbadness:=save_vbadness; vfuzz:=save_vfuzz;
after.

20. Module 917 computes |page_size| improperly. (Noticed 10/21/82)
Delete the statement "page_so_far[1]:=page_so_far[1]+width(q);"
and change the preceding statement to:
	page_size:=page_size-h-width(q);
(The comment about page_so_far in the first paragraph of module 895 is
correct; I mistakenly introduced a bug in module 917 some months after
writing the first draft of the code, believing that I was making the
algorithm more elegant or something.)

** Version 0.4 incorporates the above changes.

21. Since TeX82 applied to (the "woven" documentation) TEX.TEX uses
about 11500 words of variable-size memory, I'm increasing hi_mem_size
(in module 12) from 12000 to 13000. Actually, I recommend using considerably
larger values for mem_max and hi_mem_size, whenever possible.

22. Addition of the \boxmaxdepth parameter (10/22/82):
This involves renumbering hfuzz_code through dimen_pars, in module 234,
to numbers 9 through 18; inserting the lines
	@d box_max_depth_code=8 {maximum depth of explicit vboxes}
	@d box_max_depth==dimen_par(box_max_depth_code)
	box_max_depth_code:print_esc("boxmaxdepth");
to module 234 and
	primitive("boxmaxdepth",assign_dimen,box_max_depth_code);
to module 235; and changing the call on vpack in module 996 to
	vpackage(link(head),saved(2),saved(1),box_max_depth);

** Version 0.5 incorporates the above changes.

23. Module 1224, line 4 (bug found by GMK/HWT on 10/26/82)
change "(k+x>eqtb_size)" to "(k+x>eqtb_size+1)"

24. Module 247, line 13 (bug found 10/26/82)
(bug was reflected in TRIP.LOG but not noticed)
change "ch_code(p)" to "ch_code(p-single_base)"

25. Module 670, line 18 (bug found 10/27/82)
interchange the statements "fetch(...)" and "math_type(...):=..."
(since the fetch routine sometimes has a side-effect of changing math_type)
A major change (Version 0.6) made on October 28:
The following list of changes counts as "number 26" on the list.
Fonts now have identifiers instead of code numbers; the "\:" primitive
has disappeared; and there are associated new features for "\the".

a. In module 11, delete bad_font_code.
b. In modules 170 and 172, delete print_esc(":"), and change
	`print_int(font_code' to `sprint_cs(font_ident'.
c. In module 205, the comment for set_font is revised.
d. In module 217, there are now five locations for control sequences
	that are perpetually defined; undefined_control_sequence
	is therefore defined to be frozen_control_sequence+5.
e. In module 248, sprint_cs is now included among <Basic printing procedures>.
f. Delete the primitive ":" in modules 250 and 251.
g. Add to module 376: <Declare procedures that scan font-related stuff>
h. In module 377, seven levels are now distinguished; we define
	font_val=4, ident_val=5, tok_val=6.
i. In module 380, delete the previous cases for def_family and set_font,
	and the following takes the place of case assign_toks:
	  assign_toks,def_family,set_font,def_font: <Fetch a token list or
		font number or font identifier, provided that level=tok_val>;
j. Module 382 (which now has a new name) has this new ending:
	else if cur_cmd=assign_toks then scanned_result(equiv(m))(tok_val)
	else <Fetch a font number or a font identifier>
k. Module 389 becomes
	<Fetch a font number or a font identifier>=
	if cur_cmd=set_font then scanned_result(cur_chr)(font_val)
	else if cur_cmd=def_font then
		scanned_result(font_ident[cur_font])(ident_val)
	else	begin scan_four_bit_int;
		scanned_result(font_ident[equiv(m+cur_val)])(ident_val);
		end
l. In module 393, the relation `≠tok_val' becomes `≤mu_val'.
m. In module 426, the relation `=tok_val' becomes '≥ident_val'.
	Also add a new case to the case statement:
	  font_val: begin print(font_name[cur_val]);
		if font_size[cur_val]≠font_dsize[cur_val] then
			begin print(" at "); print_scaled(font_size[cur_val]);
			print("pt");
			end;
		end;
n. The body of module 427 becomes:
	begin p←temp_head; link(p)←null;
	if cur_val_level=ident_val then store_new_token(cs_token_flag+cur_val)
	else if cur_val≠null then
		begin r←link(cur_val); {do not copy the reference count}
		while r≠null do
			begin store_new_token(info(r)); r←link(r);
			end;
		end;
	the_toks←p;
	end
o. In module 480, delete user_font_code; there's a new comment:
	When the user defines \font\f, say, TeX assigns an internal number
	to the user's font \f. For example, if this internal number is 13,
	we will have font_ident[13]=p and equiv(p)=13, where p is the eqtb
	location of the control sequence \f.
p. In module 481, delete the declaration of font_number, and
	replace the declaration of font_code by
	  font_ident:array[internal_font_number] of pointer;
q. New stuff in module 483 (also delete references to font_number, font_code):
	define bad_font_ident=frozen_control_sequence+4 {denotes a null font}
	font_name[undefined_font]←"nullfont";
	font_ident[undefined_font]←bad_font_ident;
	text(bad_font_ident)←"nullfont"; eq_level(bad_font_ident)←level_one;
	eq_type(bad_font_ident)←set_font;
	equiv(bad_font_ident)←undefined_font;
r. In module 490, parameter u is new of type pointer, and the
	read_font_info subroutine is changed to a function that
	returns an internal_font_number. There's a new local variable
	  g:internal_font_namber; {the number to return}
	and we set g←undefined_font immediately upon entering read_font_info.
	Also set read_font_info←g just before exiting.
s. In module 491, print_int(u) becomes sprint_cs(u).
t. Delete the statements involving font_code and font_number in module 506,
	and set g←f at the end of that module.
u. The body of module 507 becomes:
	<Declare procedures that scan font-related stuff>=
	procedure scan_font_ident;
	var f:internal_font_number;
	begin <Get the next non-blank non-call...>;
	if cur_cmd=set_font then f←cur_chr
	else	begin print_nl("! Missing font identifier");
		help2("I was looking for a control sequence whose")
		("current meaning has been defined by \font.");
		back_error; f←undefined_font;
		end;
	end;
v. New beginning of module 508:
	The following routine is used to implement `\texinfo f n'.
	The boolean parameter writing is set true if the calling program
	intends to change the parameter value.
	<Declare procedures that scan font-related stuff>=
and "scan_font_number" is changed to "scan_font_ident".
w. In module 509, "print_int(font_code" becomes "sprint_cs(font_ident".
	Also "font code is defined" becomes "\font is loaded" in the help.
x. In module 940, the first line of help is changed to
	"You have to specify a font identifier,"
y. The set_font case in module 1138 reduces to
	set_font: define(cur_font_loc,data,cur_chr);
z. In module 1153, delete all the complicated stuff starting with "scan_int"
	and substitute simply this:
		scan_font_ident; define(p,data,cur_val);
		end;
aa. Change new_font to new_font(a) in module 1169, and add parameter
	  (a:small_number)
	in module 1170. Also add the label common_ending, and declare
	variable u to have type pointer. The code beginning with "scan_int"
	is changed to the following:
	  get_token;
	  if cs_ptr=0 then
		 <Complain about the missing control sequence and return>;
	  u←cs_ptr; scan_optional_equals; scan_file_name;
	  <Scan the ``at'' size specification>;
	  <If this font has already been loaded, set f to the internal
		font number and goto common_ending>;
	  f←read_font_info(u,cur_name,cur_area,s);
	  common_ending: define(u,set_font,f); font_ident[f]←u;
	  exit:end;
bb. New module 1172:
	When the user gives a new identifier to a font that was previously
	loaded, the new value becomes the font_ident of record.
	Font names `xyz' and `XYZ' are considered to be different.
	<If this font has already been loaded...>=
	for f←font_base+1 to font_ptr do
		if [the test previously in module 1174] then goto common_ending
cc. New module 1173:
	<Complain about the missing control sequence and return>=
	begin print_nl("! A font identifier must be a control sequence");
	help2("You should say, e.g., `\font\f=fontfilename'.")
	("(I'm going to ignore the \font command you just gave.)");
	back_error; return;
	end
dd. New module 1174:
	<Cases of print_cmd_chr...>=
	set_font:begin print("select font "); print(font_name[chr_code]);
		if font_size[chr_code]≠font_dsize[chr_code] then
			begin print(" at "); print_scaled(font_size[chr_code]);
			print("pt");
			end;
		end;
ee. Delete the comment at the beginning of module 1227, and delete the
	loop for k←0 to bad_font_code-1, and delete dump_int(undefined_font).
ff. Delete the repeat loop in module 1228.
gg. Change font_code to font_ident in module 1229, and change
	print_int(font_code to sprint_int(font_ident.
hh. In module 1230,
	begin undump(single_base)(undefined_control_sequence)(font_ident[k]);
	undump_qqqq(font_check[k]); [and continue as before]

The changes above have been incorporated into Version 0.6.
The ill-fated Version 0.7

27. (Here's a change that I retracted shortly after making it, since I
discovered that the source was flaky after all; and I also found a reliable
source [NBS Circular 570] confirming my original information. I include
the note here only for historical purposes...)

"After years of searching, I've finally found a definitive definition of
the printer's point; and (unfortunately) my previous conjecture was wrong.
The truth is that 83pc=35cm, exactly; so I am changing TeX to conform.
This means some changes in the comments of modules 101 and 517, and the
following changes to the program:

"27a. In modules 547 and 571, the appropriate DVI numbers are now:
	dvi_four(109375); dvi_four(2039808); {conversion ratio for sp}
"27b. The guts of module 418 become:
	if scan_keyword("in") then set_conversion(63246)(875)
	else if scan_keyword("pc") then set_conversion(12)(1)
	else if scan_keyword("cm") then set_conversion(996)(35)
	else if scan_keyword("mm") then set_conversion(498)(175)
	else if scan_keyword("bp") then set_conversion(10541)(10500)
	else if scan_keyword("dd") then set_conversion(996)(931)
	else if scan_keyword("cc") then set_conversion(11952)(931)
	else..."

*** Version 0.7 of TeX incorporated the changes above (82/10/30);
this version was withdrawn on 82/11/2.
Changes subsequent to Version 0.6

28. The experience with #27 did lead me to one improvement, thanks
to Chuck Bigelow, with respect to Didot points. (11/4/82)
Add the following comment to module 418:
	According to the definitions here, $\rm2660\,dd\approx1000.33297\,mm$;
	this agrees well with the value $\rm1000.333/,mm$ cited by Bosshard
	in {\sl Technische Grundlagen zur Satzherstellung\/} (Bern, 1980).
And change two lines of the code there as follows:
	else if scan_keyword("dd") then set_conversion(1238)(1157)
	else if scan_keyword("cc") then set_conversion(14856)(1157)

29. The new font material is made more robust by ensuring that \the\font
always returns a pointer to a control sequence whose command code is
set_font. (Change 11/4/82)

29a. The code changed in 26aa is changed again, to the following:
	<If the next token isn't a control sequence, issue a complaint and
		return; otherwise set u←cs_ptr, and set hash_used to the
		location of a ``frozen'' copy of the new font identifier>;
	define(u,set_font,undefined_font);
	scan_optional_equals; scan_file_name;
	<Scan the ``at'' size specification>;
	<If this font has already been loaded, set f to the internal
		font number and goto common_ending>;
	f←read_font_info(u,cur_name,cur_area,s);
	common_ending: equiv(u)←f; geq_define(hash_used,set_font,f);
	font_ident[f]←hash_used;
	exit:end;
29b. Instead of 26cc, here's the new module 1173:
	We reserve a special control sequence for the font identifier;
	this one cannot be redefined by the user, so it is safe to
	return it as a value of \the\font.
	<If the next token isn't a control sequence...>=
	get_token;
	if cs_ptr<hash_base then
	    begin print_nl(
	     "! A font identifier must be a multiletter control sequence");
	    help2("You should say, e.g., `\font\ffn=fontfilename'.")
	    ("(I'm going to ignore the \font command you just gave.)");
	    back_error; return;
	    end;
	repeat if hash_is_full then overflow("hash size",hash_size);
	decr(hash_used);
	until text(hash_used)=0; {search for an empty location in hash}
	u←cs_ptr; text(hash_used)←text(u); {copy the name}
	stat incr(cs_count); tats

30. Module 993, replace lines 5 to 7 (11/5/82):
else	begin if k=vmode then new_save_level(vbox_group)
	else	begin new_save_level(vtop_group); k←vmode;
		end;
	if looseness≠0 then eq_word_define(int_base+looseness_code,0);
	if hanging_indent≠0 then
		eq_word_define(dimen_base+hanging_indent_code,0);
	if par_shape_ptr≠null then eq_define(par_shape_loc,shape_ref,null);
	end;

31. Module 403, replace line 5 (11/6/82):
if cur_tok<cs_token_flag then
	begin cur_val←cur_chr;
	if cur_cmd≤right_brace then
		if cur_cmd=right_brace then incr(align_state)
		else decr(align_state);
	end

32. Improvements to error recovery for bad alignments (11/6/82):
In module 1039, replace "begin align_error; goto reswitch; end" by "align_error"
In module 1040, delete "cur_cmd←left_brace;" and "cur_cmd←right_brace;"
	and change "error" to "back_error"
In module 1041, delete "cur_cmd←relax;"

33. More power to \let (11/8/82):
33a. Module 1141 becomes:
	<Assignments>+=
	let:	begin get_token;
		if cs_ptr≠0 then <Carry out the \let operation>
		else	begin print_nl
			 ("! You can use \let only with control sequences");
			help2("I'm not \let-ting anything change here,")
				("since I can only do things like `\let\a=b'.");
			back_error;
			end;
		end;
33b. Module 1142 becomes:
	<Carry out the \let...>=
	begin p←cs_ptr;
	repeat get_token;
	until cur_cmd≠spacer;
	if cur_tok=other_token+"=" then
		begin get_token;
		if cur_cmd=spacer then get_token;
		end;
	if cur_cmd≥call then add_token_ref(cur_chr);
	define(p,cur_cmd,cur_chr);
	end

34. This change helps you see an undefined control sequence
in certain unusual cases (discovered by JDH, 11/8/82):
Add the clause "(base_ptr=input_ptr) or" to module 294, line 2.

35. Here's an improvement in the formula for demerits; previously
more weight was given to minimizing bad spacing on lines with penalties,
so that (slightly loose hyphenated line)(OK line) was considered worse
than (OK hyphenated line)(quite loose line). (fixed 11/8/82)
Change lines 2--7 of module 772 to the following:
	d←line_penalty+b; d←d*d;
	if pi≠0 then
		if pi>0 then d←d+pi*pi
		else if pi>eject_penalty then d←d-pi*pi;

36. Minor change to save buffer space in non-INITEX (11/10/82):
Enclose the declaration of pool_file in module 50 by init...tini.

37. Minor improvement in format for the context of error messages (11/13/82):
37a. Module 289, type "inserted" split into "backed_up=3", "inserted=4"
and the other type numbers increase: "macro=5", etc.
37b. In module 296, backed_up: if loc=null then print_nl("<recently read>")
			else print_nl("<to be read again> ");
		inserted: print_nl("<inserted text> ");
37c. Minor changes to comments in modules 289 and 293.
37d. Change "inserted" to "backed_up" in module 294.
37e. Add definition "back_list(#)==begin_token_list(#,backed_up)" in module 305.
37f. In module 306, first test should be "≥backed_up", second "≤inserted".
37g. Change ins_list to back_list in modules 307, 318, 375, 1195.
37h. Add definition to module 308:
	ins_error==begin back_error; token_type←inserted; end
37i. Change back_error to ins_error in modules 362, 1040, 1046.
37j. Change "<to be read again>" to "<inserted text>" in module 973 help.

38. Module 407, the error message is changed (11/11/82) to:
"! Missing number, treated as zero".

39. Fix anomaly when hbadness or vbadness is small (11/11/82):
Module 593, line 2, "if (-x-total_shrink[normal]>hfuzz) or (hbadness<100)"
Module 603, line 2, "if (-x-total_shrink[normal]>vfuzz) or (vbadness<100)"

40. Added the \tokens primitive (11/13/82):
In module 223, defined tokens_loc and tokens (analogous to every_par).
In module 225, defined the primitive.
In module 1146, changed the comment to include tokens_loc as a possibility.

41. Change get_nc_token to get_token in module 374 (11/13/82).
(In particular \def\foo{...}\foo won't say "undefined c.s." now!)
(This change later retracted during debugging; it was found that
"endv" aborts the job, so this cure was worse than the disease. Then
it was re-established as part of the major change to conditionals,
because endv needed to be more robust anyway.)

42. In module 699, we make \span expand in a preamble (11/13/82).
Change lines -7 through -3 to:
	begin get_nc_token; goto reswitch;
	end;

43. Modules 321 and 322 have been altered for better efficiency (11/12/82)
and better exposition; the three conditions of module 322 are now
in separate if tests.

44. Frozen control sequences are now unredefinable. (11/16/82)
A new procedure get_r_token has been introduced to give uniform error
messages for \def, \let, \read, \font, \mathchardef, and to make them
incapable of changing the frozen equivalents.

Incidentally, get_nc_token is changed to get_x_token; and ch_code
becomes cat_code.
A major change (Version 0.8) made on November 14--16:
Conditional statements are taken from semantics to syntax.

This change, which counts as number 45 on the list, made it necessary
to renumber the modules. And it was such a drastic change, the
differences can only be sketched here, using the old module numbers
for reference. A variety of other things were cleaned up because this
change made it more natural for them to be handled differently.

45a. Module 158, inserted a permanently empty token list called null_list.
45b. Module 204, deleted if_test, case_branch, else_code, convert;
	inserted end_cs_name.
45c. Module 206, inserted if_test, fi_or_else, cs_name, convert, and
	end_template (the latter comes after long_outer_call).
45d. Module 217, there are now nine frozen control sequences; also null_cs.
45e. Modules 247 and 248, must be able to print a null control sequence.
45f. Module 268 (leave_transparent_group) disappears; comments in the
	previous modules also are appropriately simplified.
45g. Module 273, delete endv_token.
45h. Modules 277 and 278, delete references to endv (it no longer appears).
45i. After module 281, a procedure show_cur_cmd_chr takes the
	code for tracing commands from module 937.
45j. Module 317 now forbids \outer control sequences when skipping,
	and inserts \fi in front of them, for error recovery.
45k. Module 334 now uses null_cs if carriage-return is an escape.
45l. Module 343 no longer has endv test.
45m. Module 344, major extensions to expand_calls make it several modules
	longer. It saves global variables like cur_val. It changes
	end_template to endv. It processes cs_name and convert.
	It processes if_test by calling the "conditional" procedure.
	It processes fi_or_else by checking their legality, and (if legal)
	updating the if stack.
45n. Module 373 (pass_block) disappears.
45o. After module 400, radix and cur_val and cur_val_level are initialized.
45p. Module 428 changes so that conv_toks is a procedure rather than a
	function; this procedure is invoked by expand_calls.
45q. Modules 436 and 1032, delete reference to conv_toks.
45r. After module 443, the entire part 48 moves to this part of the program,
	and the parts are renumbered accordingly. \case is changed to
	\ifcase, and it resides under the if_test command.
	New routines are inserted to maintain a linked stack that records
	the current state of conditionals. There's a procedure
	pass_text that skips text while looking for \fi or \else or \or
	on level zero with respect to \if...\fi nesting. The previous
	routines for skip control via handle_right_brace are eliminated,
	and the new ones are somewhat simpler. The new \ifcat is mostly
	combined with the old \if; they no longer ignore spaces.
	The scanner_status is set to normal while processing \ifx.
	\ifx will consider \a to equal 0 after \let\a=0.
45s. Modules 701, 707: endv_token is replaced by a token for a frozen
	control sequence whose command code end_template makes it behave
	like an outer_call. After expand_calls, it is converted to another
	frozen control sequence, whose command code is endv. This two-step
	facilitates error recovery, instead of giving a fatal error stop.
45t. Module 874, remove "pass_block(1); goto done".
45u. After module 1047, routine for end_cs_name prints an error message.
45v. Module 1049, get_nc_token becomes get_token. (else $\ifmmode fails)
45w. Module 1202 gets another case (end_template).
45x. Module 1243, new warning is printed if the if stack isn't empty.
Changes after version 0.8

46. Declare c : ascii_code in module 825 (noted by DRF, 11/21/82)

47. Module 776 lines 4-6 (suggested by DRF, 11/21/82)
threshold←pretolerance;
if threshold≥0 then
	begin stat if tracing_stats>2 then
		begin begin_diagnostic; print_nl("@@firstpass");
		end; tats
	second_pass←false;
	end
else	begin threshold←tolerance; second_pass←true;
	end;

48. Protection for DVI files (added 11/16/82)
Replace lines 2 and 3 of module 570 by:
	<Update the values of max_h and max_v; but if the page is too large,
		goto done>;
Move the statement "dead_cycles←0" from module 570 to module 568.
Declare "label done;" in module 568.
And add the following new module after 570:

@ Sometimes the user will generate a huge page because other error messages
are being ignored. Such pages are not output to the \.{dvi} file, since they
may confuse the printing software.

@<Update the values of |max_h| and |max_v|; but if the page is too large...@>=
if (height(p)>max_dimen)∨(depth(p)>max_dimen)∨(width(p)>max_dimen) then
	begin print_nl("! Huge page cannot be shipped out");
	help2("The page just created is more than 18 feet tall or")@/
	 ("more than 18 feet wide, so I suspect something went wrong.");
	error;
	if tracing_output=0 then
		begin begin_diagnostic;
		print_nl("The following box has been deleted:");
		show_box(p);
		end_diagnostic(true);
		end;
	goto done;
	end;
if height(p)+depth(p)>max_v then max_v←height(p)+depth(p);
if width(p)>max_h then max_h←width(p)

49. New features \everymath and \everydisplay (12/2/82).
Make changes analogous to those for "\tokens" (see change 40).
Put the following just before the end of module 1050:
  if every_math≠null then begin_token_list(every_math,every_math_text);
And put the following just before the end of module 1056:
  if every_display≠null then
	begin_token_list(every_display,every_display_text);

50. New feature \futurelet (12/2/82):
Module 1141 changes again. (Also, "let" and "futurelet" share cmd code "let".)
let:	begin n←cur_chr;
	get_r_token; p←cs_ptr;
	if n=normal then
		begin repeat get_token;
		until cur_cmd≠spacer;
		if cur_tok=other_token+"=" then
			begin get_token;
			if cur_cmd=spacer then get_token;
			end;
		end
	else	begin get_token; q←cur_tok; get_token; back_input;
		cur_tok←q; back_input; {look ahead, then back up}
		end; {|back_input| doesn't affect |cur_cmd|, |cur_chr|}
and continue with "if cur_cmd≥call", as before.

*** The changes above have been incorporated into version 0.9 of TeX.

51. Preview of possible coming attraction, not yet implemented (sugg by FY):
\endinput in TeX to close the current file the next time a line ends.
Plan to introduce a global variable force_eof, initially false and
cleared to false in module 339 when we prompt_input("*").
Module 340 to become:
	if not force_eof then if input_ln.... else force_eof←true;
	if force_eof then begin print_char(")"); force_eof←false;...
This requires renumbering lots of commands again.
TRIP will put an \endinput into TRIPOS.
52. Module 1005, line 4 (12/8/82)
change "if align_state<0" to "if (mode<0)or(align_state<0)"
and the comment on the next line should refer to hbox or alignment...
(This avoids embarrassing case where TeX says "type a command or say \end"
but when you type \end it says "You can't use \end in restricted horiz mode".)